#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/notifier.h>
#include <linux/delay.h>
#include <linux/slab.h>

static struct notifier_block* pnb = NULL;
static char* mstate[] = { "LIVE", "COMING", "GOING" };

// notifier callback
int get_notify(struct notifier_block* p, unsigned long v, void* m)
{
    printk("module <%s> is %s, p->priority=%d\n", ((struct module*)m)->name, mstate[v],
        p->priority);
    return 0;
}
static int hello_init(void)
{
    // alloc notifier node
    pnb = kzalloc(sizeof(struct notifier_block), GFP_KERNEL);
    if (!pnb)
        return -1;

    pnb->notifier_call = get_notify;
    pnb->priority = 10;

    // register notifier node
    register_module_notifier(pnb);
    printk("A listening module is coming...\n");
    return 0;
}

static void hello_exit(void)
{
    unregister_module_notifier(pnb);
    kfree(pnb);
    printk("A listening module is going\n");
}

module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");